home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / scope / 051-075 / scopedisk55 / sfont33 / showfont.c < prev    next >
C/C++ Source or Header  |  1995-03-19  |  30KB  |  1,213 lines

  1. /********************************************/
  2. /*   ShowFont 3.3 - by Arthur Johnson Jr.   */
  3. /* ======================================== */
  4. /* Usage: ShowFont [font_name] [font_size]  */
  5. /* ======================================== */
  6. /*    Last modifications - 02/11/89        */
  7. /********************************************/
  8.  
  9. #include "intuition/intuition.h" /* this one includes heaps o' stuff */
  10. #include "exec/memory.h"
  11. #include "libraries/diskfont.h"
  12.  
  13. #define XAREA        20        /* no characters beyond (screenwidth - XAREA) */
  14. #define FONTBUFFER  5000    /* hopefully enough for most people */
  15. #define FONTNAMELEN 30        /* maximum font name length */
  16. #define MAXFLAGS    9        /* total of nine style flags so far */
  17.  
  18. #define MAXDISPLAY  7        /* max names, sizes, and styles to display */
  19. #define NAMELEN     13        /* maximum chars of name displayed */
  20. #define NAMEXPOS    13
  21. #define SIZEXPOS    145
  22. #define STYLXPOS    197
  23. #define TOPYPOS     7
  24.  
  25. #define BASELINE    6    /* for Topaz-8 font */
  26. #define YINCR        8
  27.  
  28. /* these are short little macro expanders to save me some typing effort */
  29. #define SIZES        fonts[namesel].sizes
  30. #define SIZESEL     fonts[namesel].sizesel
  31. #define STYLES        fonts[namesel].size[SIZESEL].styles
  32. #define STYLE        fonts[namesel].size[SIZESEL].style
  33. #define STYLESEL    fonts[namesel].size[SIZESEL].stylesel
  34.  
  35. extern struct NewScreen newscreen;
  36. extern struct Gadget W_Prop;
  37. extern struct Menu Menu1;
  38. extern struct NewWindow newwindow;
  39. extern struct Requester requester1;
  40. extern struct Requester requester2;
  41. extern struct Requester RequesterStructure4;
  42. extern struct IntuiText IText19;
  43. extern struct PropInfo W_PropSInfo;
  44. extern struct PropInfo R_FontSInfo;
  45. extern struct PropInfo R_SizeSInfo;
  46. extern struct PropInfo R_StyleSInfo;
  47. extern struct Gadget R_Font;
  48. extern struct Gadget R_Size;
  49. extern struct Gadget R_Style;
  50. extern struct Border Outline1;
  51.  
  52. struct Screen *screen;
  53. struct Window *window;
  54. struct RastPort *rp;
  55. struct Gadget *whichgad;
  56. struct IntuiMessage *message;
  57.  
  58. struct IntuitionBase *IntuitionBase;
  59. struct GfxBase *GfxBase;
  60. struct DiskfontBase *DiskfontBase;
  61.  
  62. struct sizenode {
  63.     UWORD ysize;
  64.     int   styles;
  65.     UBYTE style[MAXFLAGS];
  66.     UBYTE flags;
  67.     int   stylesel;
  68. };
  69.  
  70. struct tempsizenode {
  71.     UWORD ysize;
  72.     int   styles;
  73.     UBYTE style[MAXFLAGS];
  74.     UBYTE flags;
  75.     struct tempsizenode *prev;
  76.     struct tempsizenode *next;
  77. };
  78.  
  79. struct fontinfo {
  80.     char    name[FONTNAMELEN + 1];
  81.     int     sizes;
  82.     struct  sizenode *size;
  83.     int     sizesel;
  84. };
  85. struct fontinfo *fonts;
  86.  
  87. struct tempfontinfo {
  88.     char    name[FONTNAMELEN + 1];
  89.     int     sizes;
  90.     struct  tempsizenode *size;
  91.     struct  tempfontinfo *prev;
  92.     struct  tempfontinfo *next;
  93. };
  94. struct tempfontinfo *tempfonts;
  95.  
  96. char fontname[FONTNAMELEN + 6]; /* include space for '.font\0' */
  97. struct TextAttr myfont = { /* necessary structure for fonts */
  98.     &fontname[0],   /* default is Topaz-8 fault */
  99.     8,
  100.     FS_NORMAL,
  101.     FPF_ROMFONT };
  102. struct TextFont *font;
  103.  
  104. struct {
  105.     UBYTE *string;
  106.     int length;
  107. } fontline[256];    /* maximum of 256 lines (one char/line) */
  108.  
  109. /* I just don't want to pass the following values around */
  110.  
  111. int numfonts;
  112.  
  113. int screenwidth, screenheight;
  114.  
  115. int nameline, sizeline, styleline,
  116.     namesel,
  117.     rfontlastline, rsizelastline, rstylelastline;
  118.  
  119. USHORT fontpropsize, fontproppos, sizepropsize, sizeproppos,
  120.     stylepropsize, styleproppos;
  121.  
  122. UBYTE qualifiers[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  123.                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  124.                0, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 0, 0, 0, 0,
  125.                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 2, 2,
  126.                2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  127.                2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 2, 2,
  128.                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  129.                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 5,
  130.                5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
  131.                5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
  132.                3, 4, 4, 4, 4, 4, 4, 3, 4, 4, 4, 4, 3, 3, 3, 3,
  133.                3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 3, 4, 4,
  134.                4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
  135.                4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 4, 4,
  136.                3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
  137.                3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 3 };
  138.  
  139. char whichkey[] = { '?', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
  140.             'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
  141.             'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
  142.             'X', 'Y', 'Z', '?', '?', '?', '?', '?',
  143.             's', '1', '\'', '3', '4', '5', '7', '\'',
  144.             '9', '0', '8', '=', ',', '-', '.', '/',
  145.             '0', '1', '2', '3', '4', '5', '6', '7',
  146.             '8', '9', ';', ';', ',', '=', '.', '/',
  147.             '2', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
  148.             'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
  149.             'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
  150.             'X', 'Y', 'Z', '[', '\\', ']', '6', '-',
  151.             '`', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
  152.             'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
  153.             'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
  154.             'X', 'Y', 'Z', '[', '\\', ']', '`', '?',
  155.             '?', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
  156.             'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
  157.             'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
  158.             'X', 'Y', 'Z', '?', '?', '?', '?', '?',
  159.             's', '1', '\'', '3', '4', '5', '7', '\'',
  160.             '9', '0', '8', '=', ',', '-', '.', '/',
  161.             '0', '1', '2', '3', '4', '5', '6', '7',
  162.             '8', '9', ';', ';', '-', '=', '.', '/',
  163.             '2', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
  164.             'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
  165.             'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
  166.             'X', 'Y', 'Z', '[', '\\', ']', '6', '-',
  167.             '\'', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
  168.             'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
  169.             'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
  170.             'X', 'Y', 'Z', '[', '\\', ']', '\'', 'm' };
  171.  
  172. void clearfonts()
  173. {
  174.  
  175.     register i;
  176.  
  177.     for (i = 0; i < numfonts; i++)
  178.     FreeMem(fonts[i].size, fonts[i].sizes * sizeof(struct sizenode));
  179.     FreeMem(fonts, numfonts * sizeof(struct fontinfo));
  180.  
  181.     numfonts = 0;   /* there are no fonts */
  182.  
  183. }
  184.  
  185. void clearfontlines()
  186. {
  187.  
  188.     register i = 0;
  189.  
  190.     while (fontline[i].length != 0) {
  191.     FreeMem(fontline[i].string, fontline[i].length);
  192.     fontline[i].length = 0;
  193.     ++i;
  194.     }
  195.  
  196. }
  197.  
  198. void cleanup(text)
  199. char *text;
  200. {
  201.  
  202.     clearfontlines();
  203.     clearfonts();
  204.     if (font)
  205.     CloseFont(font);
  206.     if (window) {
  207.     ClearMenuStrip(window);
  208.     CloseWindow(window);
  209.     }
  210.     if (screen)
  211.     CloseScreen(screen);
  212.     if (DiskfontBase)
  213.     CloseLibrary(DiskfontBase);
  214.     if (IntuitionBase)
  215.     CloseLibrary(IntuitionBase);
  216.     if (GfxBase)
  217.     CloseLibrary(GfxBase);
  218.  
  219.     if (text)
  220.     puts(text);
  221.  
  222.     exit(0);
  223.  
  224. }
  225.  
  226. void cleartempsize(font)
  227. struct tempfontinfo *font;
  228. {
  229.  
  230.     struct tempsizenode *erase;
  231.  
  232.     while (font->size != NULL) {
  233.     erase = font->size;
  234.     font->size = font->size->next;
  235.     FreeMem(erase, sizeof(struct tempsizenode));
  236.     }
  237.  
  238. }
  239.  
  240. void cleartempfonts()
  241. {
  242.  
  243.     struct tempfontinfo *erase;
  244.  
  245.     while (tempfonts != NULL) {
  246.     erase = tempfonts;
  247.     tempfonts = tempfonts->next;
  248.     cleartempsize(erase);
  249.     FreeMem(erase, sizeof(struct tempfontinfo));
  250.     }
  251.  
  252. }
  253.  
  254. int stylenum(style)
  255. UBYTE style;
  256. {
  257.  
  258.     if (style == FS_NORMAL)
  259.     return(0);
  260.     if (style & FSF_UNDERLINED)
  261.     return(1);
  262.     if (style & FSF_BOLD)
  263.     return(2);
  264.     if (style & FSF_ITALIC)
  265.     return(4);
  266.     if (style & FSF_EXTENDED)
  267.     return(8);
  268.  
  269. }
  270.  
  271. void addsizenode(font, ysize, style, flags)
  272. struct tempfontinfo *font;
  273. UWORD ysize;
  274. UBYTE style;
  275. UBYTE flags;
  276. {
  277.  
  278.     struct tempsizenode *search, *prev, *newnode;
  279.  
  280.     int foundit = FALSE;
  281.  
  282.     prev = NULL;
  283.     search = font->size;
  284.     while (search != NULL) {
  285.     if ((search->ysize == ysize) && (search->flags == flags)) {
  286.         search->style[search->styles] = stylenum(style);
  287.         ++(search->styles);
  288.         foundit = TRUE;
  289.         break;
  290.     }
  291.     else {
  292.         if (search->ysize >= ysize) /* should go before this size */
  293.         break;
  294.         else {
  295.         prev = search;
  296.         search = search->next;
  297.         }
  298.     }
  299.     }
  300.     if (!foundit) {
  301.     newnode = (struct tempsizenode *)AllocMem(sizeof(struct tempsizenode), MEMF_CLEAR);
  302.     if (newnode == NULL)
  303.         cleanup("ShowFont: couldn't allocate 'tempsizenode' memory!");
  304.     newnode->ysize = ysize;
  305.     newnode->styles = 0;
  306.     newnode->flags = flags;
  307.     newnode->style[newnode->styles] = stylenum(style);
  308.     ++(newnode->styles);
  309.     ++(font->sizes);
  310.     if (font->size == NULL) {   /* list is empty */
  311.         newnode->prev = NULL;
  312.         newnode->next = NULL;
  313.         font->size = newnode;
  314.     }
  315.     else {
  316.         if (search == NULL) {   /* add at end o' list */
  317.         prev->next = newnode;
  318.         newnode->prev = prev;
  319.         newnode->next = NULL;
  320.         }
  321.         else {
  322.         if (search->prev == NULL) { /* add at beginning o' list */
  323.             newnode->prev = NULL;
  324.             newnode->next = search;
  325.             search->prev = newnode;
  326.             font->size = newnode;
  327.         }
  328.         else {    /* add in the middle o' the list */
  329.             search->prev->next = newnode;
  330.             newnode->prev = search->prev;
  331.             newnode->next = search;
  332.             search->prev = newnode;
  333.         }
  334.         }
  335.     }
  336.     }
  337.  
  338. }
  339.  
  340. void readfonts()
  341. {
  342.  
  343.     struct AvailFontsHeader *afh;
  344.     struct AvailFonts *af;
  345.  
  346.     struct tempfontinfo *search, *prev, *newnode;
  347.     struct tempsizenode *sizenode;
  348.  
  349.     char searchname[FONTNAMELEN + 6];
  350.  
  351.     int foundit;
  352.  
  353.     int mem = FONTBUFFER,
  354.     moremem;
  355.  
  356.     register i, j, k;
  357.  
  358.     clearfonts();
  359.  
  360.     do {
  361.     afh = (struct AvailFontsHeader *)AllocMem(mem, MEMF_CLEAR);
  362.     if (afh == NULL)
  363.         cleanup("ShowFont: couldn't allocate 'AvailFontsHeader' memory!");
  364.     moremem = AvailFonts(afh, mem, 0xFF);
  365.     if (moremem != 0) {
  366.         FreeMem(afh, mem);
  367.         mem += moremem;
  368.         printf("ShowFont: allocating %d bytes of memory for the FONTS: info.\n", mem);
  369.     }
  370.     } while (moremem != 0);
  371.  
  372.     if (afh->afh_NumEntries == 0) {
  373.     FreeMem(afh, mem);
  374.     cleanup("ShowFont: couldn't find any fonts! (Is FONTS: set correctly?)");
  375.     }
  376.  
  377.     tempfonts = NULL;
  378.  
  379.     af = (struct AvailFonts *)&afh[1];
  380.     for (i = 0; i < afh->afh_NumEntries; i++) {
  381.     if (!((af->af_Attr.ta_Flags & FPF_REMOVED) ||
  382.         (af->af_Attr.ta_Flags & FPF_REVPATH) ||
  383.         ((af->af_Type & AFF_MEMORY) &&
  384.          (af->af_Attr.ta_Flags & FPF_DISKFONT)))) {
  385.  
  386.         prev = NULL;
  387.         search = tempfonts;
  388.         foundit = FALSE;
  389.         while (search != NULL) {
  390.         strcpy(searchname, search->name);
  391.         strcat(searchname, ".font");
  392.         if (stricmp(af->af_Attr.ta_Name, searchname) == NULL) {
  393.             addsizenode(search, af->af_Attr.ta_YSize, af->af_Attr.ta_Style, af->af_Attr.ta_Flags);
  394.             foundit = TRUE;
  395.             break;
  396.         }
  397.         else {
  398.             if (stricmp(af->af_Attr.ta_Name, searchname) < NULL)
  399.             break;    /* should go before here */
  400.             else {
  401.             prev = search;
  402.             search = search->next;
  403.             }
  404.         }
  405.         }
  406.         if (!foundit) {
  407.         newnode = (struct tempfontinfo *)AllocMem(sizeof(struct tempfontinfo), MEMF_CLEAR);
  408.         if (newnode == NULL)
  409.             cleanup("ShowFont: couldn't allocate 'tempfontinfo' memory!");
  410.         stccpy(newnode->name, af->af_Attr.ta_Name, (strlen(af->af_Attr.ta_Name) - 4));
  411.         newnode->sizes = 0;
  412.         newnode->size = NULL;
  413.         addsizenode(newnode, af->af_Attr.ta_YSize, af->af_Attr.ta_Style, af->af_Attr.ta_Flags);
  414.         ++numfonts;
  415.         if (tempfonts == NULL) { /* list is empty */
  416.             newnode->prev = NULL;
  417.             newnode->next = NULL;
  418.             tempfonts = newnode;
  419.         }
  420.         else {
  421.             if (search == NULL) {   /* should add at end */
  422.             prev->next = newnode;
  423.             newnode->prev = prev;
  424.             newnode->next = NULL;
  425.             }
  426.             else {
  427.             if (search->prev == NULL) { /* add at beginning */
  428.                 newnode->prev = NULL;
  429.                 newnode->next = search;
  430.                 search->prev = newnode;
  431.                 tempfonts = newnode;
  432.             }
  433.             else { /* add in the middle o' the list */
  434.                 search->prev->next = newnode;
  435.                 newnode->prev = search->prev;
  436.                 newnode->next = search;
  437.                 search->prev = newnode;
  438.             }
  439.             }
  440.         }
  441.         }
  442.     }
  443.     af++;
  444.     }
  445.  
  446.     FreeMem(afh, mem);
  447.  
  448.     if ((fonts = (struct fontinfo *)AllocMem(numfonts * sizeof(struct fontinfo), MEMF_CLEAR)) == NULL)
  449.     cleanup("ShowFont: couldn't allocate 'fontinfo' memory!");
  450.  
  451.     search = tempfonts;
  452.  
  453.     for (i = 0; i < numfonts; i++) {
  454.     strcpy(fonts[i].name, search->name);
  455.     fonts[i].sizes = search->sizes;
  456.     if ((fonts[i].size = (struct sizenode *)AllocMem(fonts[i].sizes * sizeof(struct sizenode), MEMF_CLEAR)) == NULL)
  457.         cleanup("ShowFont: couldn't allocate 'sizenode' memory!");
  458.     sizenode = search->size;
  459.     for (j = 0; j < fonts[i].sizes; j++) {
  460.         fonts[i].size[j].ysize = sizenode->ysize;
  461.         fonts[i].size[j].styles = sizenode->styles;
  462.         for (k = 0; k < fonts[i].size[j].styles; k++)
  463.         fonts[i].size[j].style[k] = sizenode->style[k];
  464.         fonts[i].size[j].stylesel = 0;
  465.         fonts[i].size[j].flags = sizenode->flags;
  466.         sizenode = sizenode->next;
  467.     }
  468.     fonts[i].sizesel = 0;
  469.     search = search->next;
  470.     }
  471.  
  472.     cleartempfonts();
  473.  
  474. }
  475.  
  476. void setupscreen()
  477. {
  478.  
  479.     if (window) {
  480.     ClearMenuStrip(window);
  481.     CloseWindow(window);
  482.     }
  483.     if (screen)
  484.     CloseScreen(screen);
  485.  
  486.     newscreen.Width = screenwidth;
  487.     newscreen.Height = screenheight;
  488.     if (screenwidth == 320)
  489.     if (screenheight == 200)
  490.         newscreen.ViewModes = NULL;
  491.     else
  492.         newscreen.ViewModes = LACE;
  493.     else
  494.     if (screenheight == 200)
  495.         newscreen.ViewModes = HIRES;
  496.     else
  497.         newscreen.ViewModes = HIRES | LACE;
  498.  
  499.     newwindow.Width = screenwidth;
  500.     newwindow.Height = screenheight;
  501.  
  502.     if (screenwidth == 320) {
  503.     requester1.LeftEdge = 0;
  504.     requester2.LeftEdge = 56;
  505.     RequesterStructure4.LeftEdge = 80;
  506.     }
  507.     else {
  508.     requester1.LeftEdge = 160;
  509.     requester2.LeftEdge = 216;
  510.     RequesterStructure4.LeftEdge = 240;
  511.     }
  512.  
  513.     if (screenheight == 200) {
  514.     requester1.TopEdge = 50;
  515.     requester2.TopEdge = 50;
  516.     RequesterStructure4.TopEdge = 75;
  517.     }
  518.     else {
  519.     requester1.TopEdge = 150;
  520.     requester2.TopEdge = 150;
  521.     RequesterStructure4.TopEdge = 175;
  522.     }
  523.  
  524.     if ((screen = (struct Screen *)OpenScreen(&newscreen)) == NULL)
  525.     cleanup("ShowFont: couldn't open the screen.");
  526.     newwindow.Screen = screen;
  527.  
  528.     if ((window = (struct Window *)OpenWindow(&newwindow)) == NULL)
  529.     cleanup("ShowFont: couldn't open the window.");
  530.     rp = window->RPort;
  531.  
  532.     SetMenuStrip(window, &Menu1);
  533.  
  534. }
  535.  
  536. int findfont()
  537. {
  538.  
  539.     char searchname[FONTNAMELEN + 6];
  540.  
  541.     int low, mid, high;
  542.  
  543.     low = 0;
  544.     high = numfonts - 1;
  545.     while (low <= high) {
  546.     mid = (low + high) / 2;
  547.     strcpy(searchname, fonts[mid].name);
  548.     strcat(searchname, ".font");
  549.     if (stricmp(fontname, searchname) < 0)
  550.         high = mid - 1;
  551.     else
  552.         if (stricmp(fontname, searchname) > 0)
  553.         low = mid + 1;
  554.         else
  555.         return(mid);
  556.     }
  557.  
  558.     return(-1);
  559.  
  560. }
  561.  
  562. USHORT proppos(line, maxline)
  563. int line;
  564. int maxline;
  565. {
  566.  
  567.     if (maxline == 1)
  568.     return((USHORT)MAXBODY);
  569.     else
  570.     return((USHORT)((MAXBODY * (line - 1)) / (maxline - 1)));
  571.  
  572. }
  573.  
  574. USHORT propsize(display, maxdisplay)
  575. int display;
  576. int maxdisplay;
  577. {
  578.  
  579.     if (display >= maxdisplay)
  580.     return((USHORT)MAXPOT);
  581.     else
  582.     return((USHORT)((MAXPOT * display) / maxdisplay));
  583.  
  584. }
  585.  
  586. int propline(proppos, maxline)
  587. USHORT proppos;
  588. int maxline;
  589. {
  590.  
  591.     return((proppos * maxline) / MAXPOT);
  592.  
  593. }
  594.  
  595. void refresh1(rp)
  596. struct RastPort *rp;
  597. {
  598.  
  599.     register loop,
  600.          x = NAMEXPOS,
  601.          y = TOPYPOS + BASELINE;
  602.  
  603.     char namestring[NAMELEN + 1];
  604.  
  605.     SetDrMd(rp, JAM2);
  606.     SetAPen(rp, 1);
  607.  
  608.     for (loop = 0; loop < MAXDISPLAY; loop++) {
  609.     Move(rp, x, y);
  610.     SetBPen(rp, 0);
  611.     if ((nameline + loop) < numfonts) {
  612.         if ((nameline + loop) == namesel)
  613.         SetBPen(rp, 2);
  614.         sprintf(namestring, "%-13s", fonts[nameline + loop].name);
  615.         Text(rp, namestring, NAMELEN);
  616.     }
  617.     else
  618.         Text(rp, "             ", NAMELEN);
  619.     y += YINCR;
  620.     }
  621.  
  622. }
  623.  
  624. void refresh2(rp)
  625. struct RastPort *rp;
  626. {
  627.  
  628.     register loop,
  629.          x = SIZEXPOS,
  630.          y = TOPYPOS + BASELINE;
  631.  
  632.     char sizestring[3 + 1];
  633.  
  634.     SetDrMd(rp, JAM2);
  635.  
  636.     for (loop = 0; loop < MAXDISPLAY; loop++) {
  637.     Move(rp, x, y);
  638.     SetBPen(rp, 0);
  639.     if ((sizeline + loop) < SIZES) {
  640.         SetAPen(rp, 1);
  641.         if (fonts[namesel].size[sizeline + loop].flags & FPF_PROPORTIONAL)
  642.         SetAPen(rp, 3);
  643.         if ((sizeline + loop) == SIZESEL)
  644.         SetBPen(rp, 2);
  645.         sprintf(sizestring, "%3d", fonts[namesel].size[sizeline + loop].ysize);
  646.         Text(rp, sizestring, 3);
  647.     }
  648.     else
  649.         Text(rp, "   ", 3);
  650.     y += YINCR;
  651.     }
  652.  
  653. }
  654.  
  655. void refresh3(rp)
  656. struct RastPort *rp;
  657. {
  658.  
  659.     register x = STYLXPOS,
  660.          y = TOPYPOS + BASELINE,
  661.          loop;
  662.  
  663.     SetDrMd(rp, JAM2);
  664.     SetAPen(rp, 1);
  665.  
  666.     for (loop = 0; loop < MAXDISPLAY; loop++) {
  667.     Move(rp, x, y);
  668.     if ((loop + styleline) == STYLESEL)
  669.         SetBPen(rp, 2);
  670.     else
  671.         SetBPen(rp, 0);
  672.     if ((loop + styleline) < STYLES) {
  673.         switch(STYLE[(loop + styleline)]) {
  674.         case 0: Text(rp, "Normal      ", 12);
  675.             break;
  676.         case 1: Text(rp, "Underlined  ", 12);
  677.             break;
  678.         case 2: Text(rp, "Bold        ", 12);
  679.             break;
  680.         case 4: Text(rp, "Italic      ", 12);
  681.             break;
  682.         case 8: Text(rp, "Extended    ", 12);
  683.             break;
  684.         }
  685.     }
  686.     else
  687.         Text(rp, "            ", 12);
  688.     y += YINCR;
  689.     }
  690.  
  691. }
  692.  
  693. void updateprop(prop, requester, proppos, propsize)
  694. struct Gadget *prop;
  695. struct Requester *requester;
  696. USHORT proppos;
  697. USHORT propsize;
  698. {
  699.  
  700.     NewModifyProp(prop, window, requester, AUTOKNOB | FREEVERT, -1, proppos, -1, propsize, 1);
  701.  
  702. }
  703.  
  704. /* updatetype =  1 : refresh 1        */
  705. /*             update 2, 3    */
  706. /*             refresh 2, 3   */
  707. /*         2 : refresh 2        */
  708. /*             update 3        */
  709. /*             refresh 3        */
  710. /*         3 : refresh 3        */
  711. /*        10 : arrow 1, u/r 1 */
  712. /*        20 : arrow 2, u/r 2 */
  713. /*        30 : arrow 3, u/r 3 */
  714. void duhprop(rp, updatetype)
  715. struct RastPort *rp;
  716. int updatetype;
  717. {
  718.  
  719.     if (updatetype == 1) {
  720.     rsizelastline = (SIZES - MAXDISPLAY) + 1;
  721.     if (rsizelastline < 1)
  722.         rsizelastline = 1;
  723.     sizeline = SIZESEL;
  724.     if ((sizeline + 1) >= rsizelastline)
  725.         sizeline = rsizelastline - 1;
  726.     sizepropsize = propsize(MAXDISPLAY, SIZES);
  727.     sizeproppos = proppos((sizeline + 1), rsizelastline);
  728.     }
  729.     if (updatetype <= 3) {
  730.     rstylelastline = (STYLES - MAXDISPLAY) + 1;
  731.     if (rstylelastline < 1)
  732.         rstylelastline = 1;
  733.     styleline = STYLESEL;
  734.     if ((styleline + 1) >= rstylelastline)
  735.         styleline = rstylelastline - 1;
  736.     stylepropsize = propsize(MAXDISPLAY, STYLES);
  737.     styleproppos = proppos((styleline + 1), rstylelastline);
  738.     }
  739.  
  740.     switch (updatetype) {
  741.      case 10: fontproppos = proppos((nameline + 1), rfontlastline);
  742.           break;
  743.      case 20: sizeproppos = proppos((sizeline + 1), rsizelastline);
  744.           break;
  745.      case 30: styleproppos = proppos((styleline + 1), rstylelastline);
  746.           break;
  747.     }
  748.  
  749.     switch (updatetype) {
  750.     case  1: refresh1(rp);
  751.          updateprop(&R_Size, &requester1, sizeproppos, sizepropsize);
  752.          updateprop(&R_Style, &requester1, styleproppos, stylepropsize);
  753.          refresh2(rp);
  754.          refresh3(rp);
  755.          break;
  756.     case  2: refresh2(rp);
  757.          updateprop(&R_Style, &requester1, styleproppos, stylepropsize);
  758.          refresh3(rp);
  759.          break;
  760.     case  3: refresh3(rp);
  761.          break;
  762.     case 10: updateprop(&R_Font, &requester1, fontproppos, fontpropsize);
  763.          refresh1(rp);
  764.          break;
  765.     case 20: updateprop(&R_Size, &requester1, sizeproppos, sizepropsize);
  766.          refresh2(rp);
  767.          break;
  768.     case 30: updateprop(&R_Style, &requester1, styleproppos, stylepropsize);
  769.          refresh3(rp);
  770.          break;
  771.     }
  772.  
  773. }
  774.  
  775. int selectfont()
  776. {
  777.  
  778.     struct RastPort *rp;
  779.  
  780.     int returnvalue,
  781.     refreshhow,
  782.     x, y;
  783.  
  784.     ULONG  class;
  785.  
  786.     Request(&requester1, window);
  787.     rp = requester1.ReqLayer->rp;
  788.  
  789.     namesel = findfont();
  790.  
  791.     rfontlastline = numfonts - MAXDISPLAY + 1;
  792.     if (rfontlastline < 1)
  793.     rfontlastline = 1;
  794.     fontpropsize = propsize(MAXDISPLAY, numfonts);
  795.  
  796.     nameline = namesel;
  797.     if ((nameline + 1) >= rfontlastline)
  798.     nameline = rfontlastline - 1;
  799.  
  800.     duhprop(rp, 1);
  801.     duhprop(rp, 10);
  802.  
  803.     DrawBorder(rp, &Outline1, 0, 0);
  804.  
  805.     refreshhow = 0;
  806.     returnvalue = 0;
  807.  
  808.     while (returnvalue == 0) {
  809.     switch (refreshhow) {
  810.         case  1: if (nameline > 0)
  811.              --nameline;
  812.              duhprop(rp, 10);
  813.              break;
  814.         case  2: nameline = propline(R_FontSInfo.VertPot, rfontlastline);
  815.              if ((nameline + 1) >= rfontlastline)
  816.              nameline = rfontlastline - 1;
  817.              refresh1(rp);
  818.              break;
  819.         case  3: if ((nameline + 1) < rfontlastline)
  820.              ++nameline;
  821.              duhprop(rp, 10);
  822.              break;
  823.         case  4: if (sizeline > 0)
  824.              --sizeline;
  825.              duhprop(rp, 20);
  826.              break;
  827.         case  5: sizeline = propline(R_SizeSInfo.VertPot, rsizelastline);
  828.              if ((sizeline + 1) >= rsizelastline)
  829.              sizeline = rsizelastline - 1;
  830.              refresh2(rp);
  831.              break;
  832.         case  6: if ((sizeline + 1) < rsizelastline)
  833.              ++sizeline;
  834.              duhprop(rp, 20);
  835.              break;
  836.         case  7: if (styleline > 0)
  837.              --styleline;
  838.              duhprop(rp, 30);
  839.              break;
  840.         case  8: styleline = propline(R_StyleSInfo.VertPot, rstylelastline);
  841.              if ((styleline + 1) >= rstylelastline)
  842.              styleline = rstylelastline - 1;
  843.              refresh3(rp);
  844.              break;
  845.         case  9: if ((styleline + 1) < rstylelastline)
  846.              ++styleline;
  847.              duhprop(rp, 30);
  848.              break;
  849.     }
  850.  
  851.     message = (struct IntuiMessage *)GetMsg(window->UserPort);
  852.     if (message != 0) {
  853.         class = message->Class;
  854.         x = message->MouseX - requester1.LeftEdge;
  855.         y = message->MouseY - requester1.TopEdge;
  856.         whichgad = (struct Gadget *)message->IAddress;
  857.         ReplyMsg(message);
  858.  
  859.         if (class == GADGETDOWN) {
  860.         refreshhow = whichgad->GadgetID;
  861.         }
  862.         if (class == GADGETUP) {
  863.         switch (whichgad->GadgetID) {
  864.             case 101: returnvalue = 1;
  865.                   break;
  866.             case 102: returnvalue = -1;
  867.                   break;
  868.         }
  869.         refreshhow = 0; /* no more auto-scrolling */
  870.         }
  871.         if (class == MOUSEBUTTONS) {
  872.         if ((y >= 0) && (y < 100) && (x >= 0) && (x < 320)) {
  873.             y -= TOPYPOS;
  874.             y = y / YINCR;
  875.             if (y < MAXDISPLAY) {
  876.             if ((x >= NAMEXPOS) && (x < (NAMEXPOS + NAMELEN * 8))) {
  877.                 if (namesel == (nameline + y)) {
  878.                 returnvalue = 1;
  879.                 EndRequest(&requester1, window);
  880.                 }
  881.                 else {
  882.                 namesel = nameline + y;
  883.                 if (namesel >= numfonts)
  884.                     namesel = numfonts - 1;
  885.                 duhprop(rp, 1);
  886.                 }
  887.             }
  888.             if ((x >= SIZEXPOS) && (x < (SIZEXPOS + 3 * 8))) {
  889.                 if (SIZESEL == (sizeline + y)) {
  890.                 returnvalue = 1;
  891.                 EndRequest(&requester1, window);
  892.                 }
  893.                 else {
  894.                 SIZESEL = sizeline + y;
  895.                 if (SIZESEL >= SIZES)
  896.                     SIZESEL = SIZES - 1;
  897.                 duhprop(rp, 2);
  898.                 }
  899.             }
  900.             if ((x >= STYLXPOS) && (x < (STYLXPOS + 12 * 8))) {
  901.                 if (STYLESEL == (styleline + y)) {
  902.                 returnvalue = 1;
  903.                 EndRequest(&requester1, window);
  904.                 }
  905.                 else {
  906.                 STYLESEL = styleline + y;
  907.                 if (STYLESEL >= STYLES)
  908.                     STYLESEL = STYLES - 1;
  909.                 duhprop(rp, 3);
  910.                 }
  911.             }
  912.             }
  913.         }
  914.         }
  915.     }
  916.     }
  917.  
  918.     if (returnvalue == 1) {
  919.     strcpy(fontname, fonts[namesel].name);
  920.     strcat(fontname, ".font");
  921.     myfont.ta_YSize = fonts[namesel].size[SIZESEL].ysize;
  922.     myfont.ta_Style = STYLE[STYLESEL];
  923.     myfont.ta_Flags = fonts[namesel].size[SIZESEL].flags;
  924.     }
  925.  
  926.     return(returnvalue);
  927.  
  928. }
  929.  
  930. void mycat(s, c)
  931. char *s;
  932. char c;
  933. {
  934.  
  935.     while (*s++ != '\0') {}
  936.     *(s - 1) = c;
  937.     *s = '\0';
  938.  
  939. }
  940.  
  941. void main(argc,argv)
  942. int argc;
  943. char *argv[];
  944. {
  945.  
  946.     int cont = TRUE,
  947.     rethinkfont = TRUE;
  948.  
  949.     ULONG   class;
  950.     USHORT  code;
  951.  
  952.     int line, maxline,
  953.     yarea,
  954.     startchar,
  955.     len, pixels,
  956.     whichmenu, whichitem,
  957.     wproplastline,
  958.     refreshhow,
  959.     x, y;
  960.  
  961.     char windowtitle[81];
  962.  
  963.     USHORT numy, pos, size;
  964.  
  965.     register loop, i;
  966.  
  967.     UBYTE textline[256], character;
  968.  
  969.     if ((argc == 2) && (*argv[1] == '?'))
  970.     cleanup("Usage: ShowFont [font_name] [font_size]");
  971.  
  972.     if ((IntuitionBase = (struct IntuitionBase *)
  973.         OpenLibrary("intuition.library", 0)) == NULL)
  974.     cleanup("ShowFont: couldn't open 'intuition.library'.");
  975.  
  976.     if ((GfxBase = (struct GfxBase *)
  977.         OpenLibrary("graphics.library", 0)) == NULL)
  978.     cleanup("ShowFont: couldn't open 'graphics.library'.");
  979.  
  980.     if ((DiskfontBase = (struct DiskfontBase *)
  981.         OpenLibrary("diskfont.library", 0)) == NULL)
  982.     cleanup("ShowFont: couldn't open 'diskfont.library'.");
  983.  
  984.     screenwidth = 640;
  985.     screenheight = 200;
  986.     setupscreen();
  987.  
  988.     fonts = NULL;
  989.  
  990.     if (argc == 1)
  991.     strcpy(fontname, "Topaz.font");
  992.     else
  993.     sprintf(fontname, "%s.font", argv[1]);
  994.     if (argc < 3) {
  995.     readfonts();
  996.     selectfont();
  997.     }
  998.     else
  999.     myfont.ta_YSize = atoi(argv[2]);
  1000.  
  1001.     for (i = 0; i < 256; ++i)
  1002.     fontline[i].length = 0;
  1003.  
  1004.     while (cont) {
  1005.  
  1006.     if (rethinkfont) {
  1007.  
  1008.         if (font)
  1009.         CloseFont(font);
  1010.  
  1011.         if ((font = (struct TextFont *)OpenDiskFont(&myfont)) == NULL)
  1012.         cleanup("ShowFont: couldn't find the font.");
  1013.  
  1014.         if (myfont.ta_YSize > screenheight) {
  1015.         screenheight = 400;
  1016.         setupscreen();
  1017.         }
  1018.  
  1019.         SetFont(rp, font);
  1020.  
  1021.         clearfontlines();
  1022.  
  1023.         startchar = font->tf_LoChar;
  1024.         line = 0;
  1025.         len = 0;
  1026.  
  1027.         for (loop = font->tf_LoChar; loop <= font->tf_HiChar; ++loop) {
  1028.         textline[len++] = loop;
  1029.         pixels = TextLength(rp, textline, len) + window->BorderLeft;
  1030.         if (pixels > (screenwidth - XAREA)) {
  1031.             --len;
  1032.             fontline[line].string = (UBYTE *)AllocMem(len, MEMF_CLEAR);
  1033.             if (fontline[line].string == NULL)
  1034.             cleanup("ShowFont: couldn't allocate 'fontline' memory!");
  1035.             for (i = startchar; i < loop; ++i)
  1036.             fontline[line].string[i - startchar] = i;
  1037.             fontline[line].length = len;
  1038.             startchar = loop;
  1039.             ++line;
  1040.             len = 0;
  1041.             --loop; /* must go back and insert that character */
  1042.         }
  1043.         else
  1044.             if (loop == font->tf_HiChar) {
  1045.             fontline[line].string = (UBYTE *)AllocMem(len, MEMF_CLEAR);
  1046.             if (fontline[line].string == NULL)
  1047.                 cleanup("ShowFont: couldn't allocate 'fontline' memory!");
  1048.             for (i = startchar; i <= font->tf_HiChar; ++i)
  1049.                 fontline[line].string[i - startchar] = i;
  1050.             fontline[line].length = len;
  1051.             ++line;
  1052.             }
  1053.         }
  1054.  
  1055.         maxline = line;
  1056.         line = 0;
  1057.         yarea = screenheight - (window->BorderTop + window->BorderBottom);
  1058.         numy = yarea / font->tf_YSize;
  1059.  
  1060.         wproplastline = (maxline - numy) + 1;
  1061.         if (wproplastline < 1)
  1062.         wproplastline = 1;
  1063.  
  1064.         size = propsize(numy, maxline);
  1065.  
  1066.         stccpy(windowtitle, fontname, (strlen(fontname) - 4));
  1067.         sprintf(windowtitle + strlen(windowtitle), " - %d", myfont.ta_YSize);
  1068.         SetWindowTitles(window, windowtitle, -1);
  1069.  
  1070.         rethinkfont = FALSE;
  1071.         refreshhow = 99;    /* refresh it once only */
  1072.     }
  1073.  
  1074.     switch (refreshhow) {
  1075.         case  1: if (line > 0)
  1076.              --line;
  1077.              break;
  1078.         case  2: pos = W_PropSInfo.VertPot;
  1079.              line = propline(pos, wproplastline);
  1080.              if ((line + 1) > wproplastline)
  1081.              line = wproplastline - 1;
  1082.              break;
  1083.         case  3: if ((line + 1) < wproplastline)
  1084.              ++line;
  1085.              break;
  1086.     }
  1087.  
  1088.     if (refreshhow != 0) {
  1089.  
  1090.         pos = proppos((line + 1), wproplastline);
  1091.  
  1092.         if (refreshhow != 2)    /* don't blink the slider */
  1093.         NewModifyProp(&W_Prop, window, NULL, AUTOKNOB | FREEVERT, -1, pos, -1, size, 1);
  1094.  
  1095.         WaitTOF();  /* might just possibly reduce blinking */
  1096.         SetAPen(rp, 0); /* clear the screen */
  1097.         RectFill(rp, window->BorderLeft, window->BorderTop, (screenwidth - XAREA), (screenheight - window->BorderBottom));
  1098.  
  1099.         SetAPen(rp, 1);
  1100.         SetBPen(rp, 0);
  1101.         SetDrMd(rp, JAM2);
  1102.  
  1103.         for (i = line; i < (line + numy); ++i) {
  1104.         Move(rp, window->BorderLeft, ((i - line) * font->tf_YSize) + window->BorderTop + font->tf_Baseline);
  1105.         Text(rp, fontline[i].string, fontline[i].length);
  1106.         }
  1107.  
  1108.         if (refreshhow == 99)
  1109.         refreshhow = 0; /* for initial refreshment only */
  1110.     }
  1111.  
  1112.     message = (struct IntuiMessage *)GetMsg(window->UserPort);
  1113.     if (message != 0) {
  1114.         class = message->Class;
  1115.         code  = message->Code;
  1116.         whichgad = (struct Gadget *)message->IAddress;
  1117.         x = message->MouseX;
  1118.         y = message->MouseY;
  1119.         ReplyMsg(message);
  1120.  
  1121.         if (class == CLOSEWINDOW)
  1122.         cont = FALSE;
  1123.         if (class == GADGETDOWN)
  1124.         refreshhow = whichgad->GadgetID;
  1125.         if (class == GADGETUP)
  1126.         refreshhow = 0; /* stop scrolling */
  1127.         if (class == MOUSEBUTTONS) {
  1128.         y -= window->BorderTop;
  1129.         y /= font->tf_YSize;
  1130.         if (y < maxline) {
  1131.             for (loop = 0; loop < fontline[(y + line)].length; loop++) {
  1132.             textline[loop] = fontline[(y + line)].string[loop];
  1133.             pixels = TextLength(rp, textline, (loop + 1)) + window->BorderLeft;
  1134.             if (x <= pixels)
  1135.                 break;
  1136.             }
  1137.             character = fontline[(y + line)].string[loop];
  1138.             switch (qualifiers[character]) {
  1139.             case 0: textline[0] = '\0';
  1140.                 break;
  1141.             case 1: strcpy(textline, "CONTROL-");
  1142.                 break;
  1143.             case 2: strcpy(textline, "SHIFT-");
  1144.                 break;
  1145.             case 3: strcpy(textline, "ALT-");
  1146.                 break;
  1147.             case 4: strcpy(textline, "ALT-SHIFT-");
  1148.                 break;
  1149.             case 5: strcpy(textline, "CONTROL-ALT-");
  1150.                 break;
  1151.             }
  1152.             len = strlen(textline);
  1153.             textline[len] = whichkey[character];
  1154.             textline[len + 1] = '\0';
  1155.             IText19.LeftEdge = 80 - (strlen(textline) * 4);
  1156.             IText19.IText = textline;
  1157.             Request(&RequesterStructure4, window);
  1158.             while ((message = (struct IntuiMessage *)GetMsg(window->UserPort)) != 0)
  1159.             ReplyMsg(message);
  1160.         }
  1161.         }
  1162.         if (class == MENUPICK) {
  1163.         if (code != MENUNULL) {
  1164.             whichmenu = MENUNUM(code);
  1165.             whichitem = ITEMNUM(code);
  1166.             switch (whichmenu) {
  1167.             case 0 : switch (whichitem) {
  1168.                     case 0: Request(&requester2, window); /* about */
  1169.                         while ((message = (struct IntuiMessage *)GetMsg(window->UserPort)) != 0)
  1170.                         ReplyMsg(message);
  1171.                         break;
  1172.                     case 1: cont = FALSE; /* quit */
  1173.                         break;
  1174.                  }
  1175.                  break;
  1176.             case 1 : switch (whichitem) {
  1177.                     case 0: if (fonts == NULL)
  1178.                         readfonts();
  1179.                         if (selectfont() == 1)
  1180.                         rethinkfont = TRUE;
  1181.                         break; /* font selection */
  1182.                  }
  1183.                  break;
  1184.             case 2 : switch (whichitem) {
  1185.                     case 0: screenwidth = 320;
  1186.                         screenheight = 200;
  1187.                         setupscreen();
  1188.                         break;
  1189.                     case 1: screenwidth = 320;
  1190.                         screenheight = 400;
  1191.                         setupscreen();
  1192.                         break;
  1193.                     case 2: screenwidth = 640;
  1194.                         screenheight = 200;
  1195.                         setupscreen();
  1196.                         break;
  1197.                     case 3: screenwidth = 640;
  1198.                         screenheight = 400;
  1199.                         setupscreen();
  1200.                         break;
  1201.                  }
  1202.                  rethinkfont = TRUE;
  1203.                  break;
  1204.             }
  1205.         }
  1206.         }
  1207.     }
  1208.     }
  1209.  
  1210.     cleanup(NULL);
  1211.  
  1212. }
  1213.